package com.hitsoyauce.common;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import org.apache.commons.beanutils.BasicDynaBean;
import org.apache.commons.beanutils.BasicDynaClass;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.DynaProperty;
import org.apache.commons.validator.GenericValidator;

public class Util {
	/** 基本的日期格式 */
	public static final String DATE_PATTERN = "yy/M/d";

	/** 基本的日期时间格式 */
	public static final String DATETIME_PATTERN = "yy/M/d H:m:s";

	/** 综合检查函数返回的不同类型的数值（所代表的错误信息的含义） */
	/** 数据合法 */
	public static final int ALL_IS_OK = 0;
 
	/** 数据为空 */
	public static final int IS_NULL = 1;

	/** 数据超长 */
	public static final int OVERLENGTH = 2;

	/** 数据不是合法的数字 */
	public static final int INVALID_NUMBER = 3;

	/** 数据不是合法的日期 */
	public static final int INVALID_DATE = 4;

	/** 数据不是合法的日期/时间 */
	public static final int INVALID_TIME = 5;

	/** 数据不是合法的半角英文 */
	public static final int NOT_HALF_ENG = 6;

	/** 数据不是半角数字 */
	public static final int NOT_HALF_NUM = 7;

	/** 数据不是半角英文及数字 */
	public static final int NOT_HALF_ENG_NUM = 8;

	/** 数据不是半角英文 */
	public static final int NOT_HALF_ENG_CHR = 9;

	/** 数据不是半角英文/数字/特殊字符 */
	public static final int NOT_HALF_ENG_NUM_CHR = 10;

	/** 数据不是半角文字 */
	public static final int NOT_HALF = 11;

	/** 数据不是合法的邮件地址 */
	public static final int INVALID_MAIL = 12;

	/** 数据不是合法的URL */
	public static final int INVALID_URL = 13;

	/** 数据不是合法的文件名 */
	public static final int INVALID_FILENAME = 14;

	/** 数据不是合法的文件全名（包括路径） */
	public static final int INVALID_FULLPATH = 15;

	/** 数据不是英文/数字/特殊字符 */
	public static final int NOT_ENG_NUM_CHR = 16;

	/** 数据不是全角文字 */
	public static final int NOT_FULL = 17;

	// ******************************************************************************
	
	/**
	 * 判断输入的字符串是否为null或空（删除前后的全半角空格）
	 * 
	 * @param strIn
	 *            输入的字符串
	 * @return true 如果字符串为null或空（包括全半角空格） false 如果不是null和空
	 */
	public static boolean isNull(String strIn) {
		return strIn == null || delSpace(strIn, true).length() == 0;
	}

	/**
	 * 判断输入的字符串是否为null或空
	 * 
	 * @param s
	 *            输入的字符串
	 * @return true 如果字符串为null或空 false 如果不是null和空
	 */
	private static boolean isEmpty(String s) {
		return s == null || "".equals(s);
	}

	/**
	 * 删除前后全半角空格
	 * 
	 * @param strIn
	 *            输入的将要被删除前后空格的字符串。
	 * @param bFullSpaceDel
	 *            判断前后的全角空格是否被删除
	 * @return 删除前后空格以后的字符串
	 */
	public static String delSpace(String strIn, boolean bFullSpaceDel) {
		if (strIn == null) {
			return "";
		}

		boolean bFlag = true;
		strIn = strIn.trim();

		while (bFlag && bFullSpaceDel) {
			if (strIn.length() <= 0) {
				break;
			}
			String strStart = strIn.substring(0, 1);
			String strEnd = strIn.substring(strIn.length() - 1);

			if (strEnd.equalsIgnoreCase("　") 
			 || strEnd.equalsIgnoreCase(" ")) {
				strIn = strIn.substring(0, strIn.length() - 1);
			} else if (strStart.equalsIgnoreCase("　")
					|| strStart.equalsIgnoreCase(" ")) {
				strIn = strIn.substring(1, strIn.length());
			} else {
				bFlag = false;
			}
		}
		return strIn;
	}

	/**
	 * 取得一个字符串的字节数
	 * 
	 * @param args[0]
	 *            输入的字符串
	 * @param args[1]
	 *            字符串的编码（如：GB2312）
	 * @return 字符串的字节数
	 */
	public static int getStringByteLength(String... args) {
		if (args.length == 0) return 0;
		
		String str = args[0];
		String encoding = null;
		
		if (args.length > 1) {
			encoding = args[1];
		}
		
		if (isEmpty(str)) {
			return 0;
		}

		int len = 0;
		for (int i = 0; i < str.length(); i++) {
			try {
				byte[] b = null;
				if (!isNull(encoding)) {
					b = str.substring(i, i + 1).getBytes(encoding);
				} else {
					b = str.substring(i, i + 1).getBytes();
				}

				len += b.length;
			} catch (UnsupportedEncodingException e) {
				continue;
			}

		}
		return len;
	}

	/**
	 * 计算百分比
	 * 
	 * @param num1
	 * @param num2
	 * @return
	 */
	public static String getPercent(double num1, double num2) {
		String strPercent = "0.0";
		double num3 = num1 / num2;
		NumberFormat nf = NumberFormat.getPercentInstance();
		nf.setMinimumFractionDigits(2);
		strPercent = nf.format(num3);
		return strPercent;
	}

	/**
	 * 删除字符串中所有的空格，包括（中间和前后的全角和半角）
	 * 
	 * @param strIn
	 *            输入的字符串
	 * @param bFullSpaceDel
	 *            判断是否删除全角空格
	 * @return 删除所有空格后的字符串
	 */
	public static String delAllSpace(String strIn, boolean bFullSpaceDel) {
		StringBuffer sb = new StringBuffer();

		strIn = delSpace(strIn, bFullSpaceDel);

		for (int i = 0; i < strIn.length(); i++) {
			if (bFullSpaceDel) {
				if (strIn.charAt(i) != '　' || strIn.charAt(i) != ' ') {
					sb.append(strIn.charAt(i));
				}
			} else if (strIn.charAt(i) != ' ') {
				sb.append(strIn.charAt(i));
			}
		}
		
		return sb.toString();
	}

	/**
	 * 判断是否为一个合法的文件名（文件存在并且可读）
	 * 
	 * @param strFileName
	 *            被判断的文件名
	 * @return true 若文件存在并且可读 false 文件不存在或不可读
	 */
	public static boolean isValidFile(String strFileName) {
		if (isNull(strFileName)) return false;
		
		File fTmp = new File(strFileName);

		return fTmp.exists() && fTmp.isFile() && fTmp.canRead();
	}

	/**
	 * 判断数据是否超长
	 * 
	 * @param strIn
	 *            输入的字符
	 * @param iMaxLength
	 *            最大长度
	 * @return 超长时返回TRUE
	 */
	public static boolean isOverLength(String strIn, int iMaxLength) {
		return getStringByteLength(strIn, "gb2312") > iMaxLength;
	}

	/**
	 * 替换某个数据中的某个字符串
	 * 
	 * @param strIn
	 *            包含被替换数据的数据
	 * @param strRe
	 *            被替换的数据（原数据)
	 * @param strBy
	 *            用来替换的数据（替换后的数据）
	 * @return 替换完成后的整个数据
	 */
	public static String replace(String strIn, String strRe, String strBy) {
		int iPos;
		String strTemp = "";
		iPos = strIn.indexOf(strRe);
		while (iPos != -1) {
			strTemp += strIn.substring(0, iPos) + strBy;
			strIn = strIn.substring(iPos + strRe.length());
			iPos = strIn.indexOf(strRe);
		}
		strIn = strTemp + strIn;
		
		return strIn;
	}

	/**
	 * 将数据中的HTML TAG字符替换成相应的字符，以便在HTML/JSP页面上使用
	 * 
	 * @param strIn
	 *            被处理的数据（原数据）
	 * @return 处理后的数据
	 */
	public static String transToHtml(String strIn) {
		if (strIn == null) {
			return "";
		}
		if (strIn.equals("")) {
			return strIn;
		}
		
		strIn = strIn.replaceAll("&", "&amp;");
		strIn = strIn.replaceAll( "<", "&lt;");
		strIn = strIn.replaceAll( ">", "&gt;");
		strIn = strIn.replaceAll( "\"", "&quot;");
		strIn = strIn.replaceAll( "\r\n", "<br>");
		strIn = strIn.replaceAll( "\n", "<br>");
		strIn = strIn.replaceAll( " ", "&nbsp;");
		return strIn;
	}

	/**
	 * 将数据中的HTML TAG字符替换成相应的字符，以便在HTML/JSP页面上使用 此函数仅对HTML页面上的TextArea类型的值适用
	 * 
	 * @param strIn
	 *            被处理的值
	 * @return 处理后的值
	 */
	public static String transToHtmlTA(String strIn) {
		return transToHtml(strIn).replaceAll("<br>", "\r\n");
	}

	/**
	 * 将英文/数字/特殊记号由全角转成半角
	 * 
	 * @param s
	 *            输入的数据
	 * @return 转换后的数据
	 */
	public static String FullToHalf(String s) {
		char c;
		if (s == null) {
			return s;
		}
		if (s.length() == 0) {
			return s;
		}
		int iLen = s.length();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < iLen; i++) {
			c = s.charAt(i);
			if (c >= 0xff01 && 0xff5e > c) {
				c -= 0xfee0;
			} else if (c == 0xffe5) {
				c -= 0xff89;
			} else if (c == 0x2019) {
				c -= 0x1ff2;
			} else if (c == 0x201d) {
				c -= 0x1ffb;
			} else if (c == 0x301c) {
				c -= 0x2f9e;
			} else if (c == 0x2212) {
				c -= 0x21e5;
			} else if (c == 0x2018) {
				c -= 0x1fb8;
			} else if (c == 0x3002) {
				c -= 0x2fd4;
			} else if (c == 0x3001) {
				c -= 0x2fd5;
			} else if (c == 0x3000) {
				c -= 0x2fe0;
			}
			sb.append(c);
		}
		return new String(sb);
	}

	/**
	 * 将英文/数字/特殊记号由半角转换成全角
	 * 
	 * @param s
	 *            输入的数据
	 * @return 转换后的数据
	 */
	public static String HalfToFull(String s) {
		char c;
		if (s == null) {
			return s;
		}
		if (s.length() == 0) {
			return s;
		}
		int iLen = s.length();
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < iLen; i++) {
			c = s.charAt(i);
			if (c >= 0x0021 && 0x007e >= c) {
				c += 0xfee0;
			} else if (c == 0x005c) {
				c += 0xff89;
			} else if (c == 0x0027) {
				c += 0x1ff2;
			} else if (c == 0x0022) {
				c += 0x1ffb;
			} else if (c == 0x007e) {
				c += 0x2f9e;
			} else if (c == 0x002d) {
				c += 0x21e5;
			} else if (c == 0x0060) {
				c += 0x1fb8;
			} else if (c == 0x002e) {
				c += 0x2fd4;
			} else if (c == 0x002c) {
				c += 0x2fd5;
			} else if (c == 0x0020) {
				c += 0x2fe0;
			}
			sb.append(c);
		}
		return new String(sb);
	}

	/**
	 * 判断是否为半角数字整数
	 * 
	 * @param strIn
	 *            被判断的字符串
	 * @return true 全部字符为半角数字(整数)
	 */
	public static boolean isHalfNum(String strIn) {
		if (strIn == null) {
			return true;
		}

		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if (!(c <= 0x0039 && c >= 0x0030))
				return false;
		}
		return true;
	}

	/**
	 * 判断是否为半角英文
	 * 
	 * @param strIn
	 *            被判断的字符串
	 * @return true 全部字符为半角英文
	 */
	public static boolean isHalfEng(String strIn) {
		if (strIn == null) {
			return true;
		}
		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if ((c <= 0x007A && c >= 0x0061) == false
					&& (c <= 0x005A && c >= 0x0041) == false)
				return false;
		}
		return true;
	}

	/**
	 * 判断是否为半角的小数
	 * 
	 * @param strIn
	 *            被判断的字符串
	 * @return true 全部字符为半角数字
	 */
	public static boolean isHalfDec(String strIn) {
		if (strIn == null) {
			return true;
		}

		if (strIn.indexOf(".") != strIn.lastIndexOf(".")) {
			return false;
		}

		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if (((c <= 0x0039 && c >= 0x0030) || c == '.') == false)
				return false;
		}
		return true;
	}

	/**
	 * 判断是否为n位半角的小数  
	 * @param strIn
	 *            被判断的字符串
	 * @param length
	 *            长度
	 * @param isNegative
	 *            是否可以是负数
	 * @return true n位半角数字
	 */
	public static boolean isHalfDec(String strIn, int length, boolean isNegative) {
		if (strIn == null) {
			return true;
		}

		if (isNegative) {

			if (strIn.indexOf("-") != -1) {

				if (strIn.indexOf("-") != 0) {
					return false;
				}

				if (strIn.indexOf("-") != strIn.lastIndexOf("-")) {
					return false;
				}

				strIn = replace(strIn, "-", "");
			}
		}

		if (!isHalfDec(strIn)) {
			return false;
		}

		if (strIn.indexOf(".") > -1) {
			strIn = strIn.substring(strIn.indexOf(".") + 1);
			if (strIn.length() > length) {
				return false;
			}
		}

		return true;
	}

	/**
	 * 判断是否为半角英数字
	 * 
	 * @param strIn
	 *            被判断的字符串
	 * @return true 全部字符为半角英数字
	 */
	public static boolean isHalfEng_Num(String strIn) {
		if (strIn == null) {
			return true;
		}
		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if ((c <= 0x007A && c >= 0x0061) == false
					&& (c <= 0x005A && c >= 0x0041) == false
					&& (c <= 0x0039 && c >= 0x0030) == false)
				return false;
		}
		return true;
	}

	/**
	 * 判断是否为半角英文/数字及指定的特殊字符
	 * 
	 * @param strIn
	 *            输入的数据
	 * @param SpecialCharList
	 *            特殊字符串,中间无任何分割符,若为NULL,则为任何字符 那么此函数相当于判断是否为半角英数字
	 * @return true 若符合要求
	 */
	public static boolean isHalfEng_Num_Chr(String strIn, String SpecialCharList) {
		if (strIn == null) {
			return true;
		}

		if (isNull(SpecialCharList)) {
			return isHalf(strIn);
		}

		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if ((c <= 0x007A && c >= 0x0061) == false
					&& (c <= 0x005A && c >= 0x0041) == false
					&& (c <= 0x0039 && c >= 0x0030) == false
					&& (SpecialCharList.indexOf(String.valueOf(c)) == -1))
				return false;
		}
		return true;
	}

	/**
	 * 判断是否为英文/数字及指定的特殊字符(全角半角都可)
	 * 
	 * @param strIn
	 *            输入的数据
	 * @param SpecialCharList
	 *            特殊字符串,中间无任何分割符若为NULL,则为任何字符 那么此函数相当于判断是否为英数字
	 * @return true 若符合要求
	 */
	public static boolean isEng_Num_Chr(String strIn, String SpecialCharList) {
		if (strIn == null) {
			return true;
		}

		if (isNull(SpecialCharList)) {
			return true;
		}

		/* 全部转换成半角,然后判断 */
		strIn = FullToHalf(strIn);
		SpecialCharList = FullToHalf(SpecialCharList);

		return isHalfEng_Num_Chr(strIn, SpecialCharList);
	}

	/**
	 * 判断是否为半角文字
	 * 
	 * @param strIn
	 *            被判断的数据
	 * @return true 全部字符为半角文字
	 */
	public static boolean isHalf(String strIn) {
		if (strIn == null) {
			return true;
		}

		return strIn.getBytes().length == strIn.length();
	}

	/**
	 * 判断是否为小写英文字符
	 * 
	 * @param strIn
	 *            被判断的数据
	 * @return true 全部数据为小写的英文字符（包括全半角）
	 */
	public static boolean isLowCase(String strIn) {
		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if (!Character.isLowerCase(c)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 判断是否为小写的半角英数字
	 * 
	 * @param strIn
	 *            被判断的数据
	 * @return true 全部字符为小写的半角英数字
	 */
	public static boolean sHalfLowEng_Num(String strIn) {
		char c;
		for (int i = 0; i < strIn.length(); i++) {
			c = strIn.charAt(i);
			if ((c <= 0x007A && c >= 0x0061) == false
					&& (c <= 0x0039 && c >= 0x0030) == false)
				return false;
		}
		return true;
	}

	/**
	 * 将两个单引号替换成一个单引号
	 * 
	 * @param strIn
	 *            可能包含两个双引号的数据
	 * @return 替换后的数据
	 */
	public static String decodeSingleQuote(String strIn) {
		if (strIn == null) {
			return strIn;
		}
		strIn = replace(strIn, "''", "'");
		return strIn;
	}

	/**
	 * 将一个单引号替换成两个单引号，以便在拼写SQL语句时使用
	 * 
	 * @param strIn
	 *            可能包含单个单引号的数据
	 * @return 替换后的数据
	 */
	public static String encodeSingleQuote(String strIn) {
		if (strIn == null) {
			return strIn;
		}
		strIn = replace(strIn, "'", "''");
		return strIn;
	}

	/**
	 * 为在数据库中模糊查询而对数据做的处理
	 * 
	 * @param strIn
	 *            可能包含特殊SQL统配符的数据
	 * @param strEscape
	 *            SQL语句中的转义字符
	 * @return 替换后的数据
	 */
	public static String encodeSqlLike(String strIn, String strEscape) {
		strIn = replace(strIn, strEscape, strEscape + strEscape);
		strIn = replace(strIn,"\\","\\\\");
		strIn = replace(strIn, "%", strEscape + "%");
		strIn = replace(strIn, "_", strEscape + "_");
		strIn = replace(strIn, "％", strEscape + "％");
		strIn = replace(strIn, "＿", strEscape + "＿");
		strIn = encodeSingleQuote(strIn);
		return strIn;
	}
	
	/**
	 * 数据库查询时数组转字符串 
	 * @param a
	 * @param separator
	 * @return
	 */
	public static String arrayToString(Object[] a, String separator) {
		String result = "(";
		if (a.length > 0) {
			result += "'" + String.valueOf(a[0]) + "'"; // start with the first element
			for (int i = 1; i < a.length; i++) {
				result = result + separator + "'" + a[i] + "'";
			}
		}
		return result + ")";
	}
	
	/**
	 * 用特定的字符补充一个字符串到一个指定的总长度
	 * 
	 * @param strIn
	 *            需要被填充的字符串
	 * @param cIn
	 *            填充到里面的字符(只能是单个字符，否则不能保证填充后的长度）
	 * @param iLen
	 *            填充后的总长度
	 * @param iType
	 *            0：从前面补充字符；1：从后面补充字符
	 * @return 填充后的数据
	 */
	public static String getLenString(String strIn, char cIn, int iLen,
			int iType) {
		int iNum;
		String strRet = strIn;
		iNum = iLen - strIn.length();

		for (int i = 1; i <= iNum; i++) {
			if (iType == 0) {
				strRet = String.valueOf(cIn) + strRet;
			} else {
				strRet += String.valueOf(cIn);
			}
		}
		return strRet;
	}

	/**
	 * 保留小数点指定位数，不够的补足
	 * 
	 * @param strIn需要处理的字符串
	 * @param iLen小数点后的位数
	 * @return 保留后的数据
	 */
	public static String getFormatNumber(String strIn, int iLen) {
		int iNum;
		if (isNull(strIn)) {
			return strIn;
		}
		String strRet = strIn;

		if (strRet.startsWith(".")) {
			strRet = "0" + strRet;
		}

		if (strRet.indexOf(".") < 0) {
			iNum = iLen;
			strRet += ".";
		} else {
			iNum = iLen - (strRet.substring(strRet.indexOf(".") + 1).length());
		}

		if (iNum > 0) {
			for (int i = 1; i <= iNum; i++) {
				strRet += "0";
			}
		} else if (iNum < 0) {
			strRet = strRet.substring(0, strRet.length() + iNum + 1);
			float fTemp = Float.parseFloat(strRet);
			int iTemp = (int) (fTemp * ((int) Math.pow(10, iLen)) + 0.5f);
			strRet = String.valueOf(iTemp / 100f);
		}

		return strRet;
	}

	/**
	 * 得到指定年月的最后一天的数字值
	 * 
	 * @param iYear
	 *            指定的年
	 * @param iMonth
	 *            指定的月
	 * @return 指定年月的最后一天，若数据不合法，返回-1
	 */
	public static int getMaxDay(int iYear, int iMonth) {
		int[] monthdays = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
		if (iYear <= 0 || iMonth <= 0 || iMonth > 12) {
			return -1;
		}

		if (String.valueOf(iYear).length() <= 2) {
			if (iYear >= 0 && iYear <= 29) {
				iYear = 2000 + iYear;
			} else {
				iYear = 1900 + iYear;
			}
		} else if (String.valueOf(iYear).length() != 4) {
			return -1;
		}

		if ((iYear % 400 == 0) || ((iYear % 4 == 0) && (iYear % 100 != 0))) {
			monthdays[1] = 29;
		}
		return (monthdays[iMonth - 1]);
	}


	/**
	 * 某月的最后一天取得
	 * 
	 * @param year
	 *            年
	 * @param month
	 *            月（1－12）
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static int getLastDayInMonth(int year, int month) {
		Calendar c = Calendar.getInstance();
		c.set(c.YEAR, year - 1900);
		c.set(c.MONTH, month - 1);

		return c.getActualMaximum(c.DAY_OF_MONTH);
	}

	/**
	 * 某月的最后一天取得
	 * 
	 * @param date
	 *            日期
	 * @return
	 */
	@SuppressWarnings("static-access")
	public static int getLastDayInMonth(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		return c.getActualMaximum(c.DAY_OF_MONTH);
	}


	/**
	 * Get new date with month changed. <br>
	 * Example: 2003/04/30, 2 --> 2003/06/30, 2003/04/30, -2 --> 2003/03/02
	 * 
	 * @param now
	 *            date to be changed.
	 * @param n
	 *            int
	 * @return Date
	 */
	public static Date changeMonth(Date now, int n) {
		if (now == null) {
			return null;
		}

		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
		String s = sdf.format(now);

		sdf = new SimpleDateFormat("M");

		int m = Integer.parseInt(sdf.format(now));
		m = m + n;
		s = s.substring(0, 5) + m + s.substring(7);

		sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");

		try {
			return sdf.parse(s);
		} catch (ParseException e) {
			return null;
		}
	}

	/**
	 * Get specified date or time.
	 * 
	 * @param d
	 *            Date
	 * @param p
	 *            date pattern
	 * @return date or time in specified string pattern
	 */
	public static String getDateTime(Date d, String p) {
		if (d == null) {
			return null;
		}
		SimpleDateFormat sdf = new SimpleDateFormat(p);
		return sdf.format(d);
	}

	public static String formatMoney(String strMoney) {
		String strOut = strMoney;
		if (isNull(strOut)) {
			return "";
		}
		if (!isHalfDec(strOut)) {
			return strOut;
		}
		NumberFormat p = NumberFormat.getCurrencyInstance();
		strOut = p.format(Float.parseFloat(strOut));
		return strOut;
	}

	/**
	 * 计算某一天所在的那个星期的星期一是几号
	 * 
	 * @param date
	 *            要计算的某一天
	 * @return 某一天所在的那个星期的星期一
	 */
	public static Calendar mondayOfWeek(Calendar date) {
		Calendar monday = date;
		int def = monday.get(Calendar.DAY_OF_WEEK) - 2;
		monday.add(Calendar.DAY_OF_MONTH, -def);
		return monday;
	}

	/**
	 * 判断一个日期是否合法
	 * 
	 * @param date
	 *            要判断的日期
	 * @param dateForm
	 *            日期格式
	 * @return true：合法日期；false：不合法日期;
	 */
	public static boolean isDate(String date, String dateForm) {
		return GenericValidator.isDate(date, dateForm, true);
	}

	/**
	 * 创建一个动态Bean对象
	 * 
	 * @param propNames
	 *            属性名
	 * @param classNames
	 *            属性类型
	 * @return 动态Bean对象
	 */
	public static DynaBean createDynaBean(String[] propNames, Class<?>[] classNames) {
		DynaProperty[] props = new DynaProperty[propNames.length];
		for (int i = 0; i < propNames.length; i++) {
			props[i] = new DynaProperty(propNames[i], classNames[i]);
		}
		BasicDynaClass bdc = new BasicDynaClass(null, BasicDynaBean.class,
				props);
		DynaBean genBean = null;
		try {
			genBean = bdc.newInstance();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}
		return genBean;
	}


	/**
	 * 随机生成一个初始密码 
	 * @param id
	 * @return
	 */
	public static String generatePassword() {
		try {
			synchronized (Util.class) {
				String password = "";

				long current = System.currentTimeMillis();


				byte[] now = new Long(current).toString().getBytes();
				MessageDigest md = MessageDigest.getInstance("MD5");

				md.update(now);

				byte[] buffer = md.digest();

				StringBuffer sb = new StringBuffer(buffer.length * 2);

				for (int i = 0; i < buffer.length; i++) {
					sb.append(Character.forDigit((buffer[i] & 0xf0) >> 4, 16));
					sb.append(Character.forDigit(buffer[i] & 0x0f, 16));
				}

				password = sb.toString();

				if (password.length() > 8) {
					password = password.substring(0, 8);
				}

				return password;
			}
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}

	/**
	 * 用MD5加密编码(不可逆算法) 
	 * @param value 
	 * @return 返回编码后的一个32位长的字符串 
	 */
	public static String encodeByMd5(String value) {

		try {
			byte[] bValue = value.getBytes();
			MessageDigest md = MessageDigest.getInstance("MD5");
			md.update(bValue);

			byte[] md5Bytes = md.digest();

			StringBuffer hexValue = new StringBuffer();

			for (int i = 0; i < md5Bytes.length; i++) {

				int val = ((int) md5Bytes[i]) & 0xff;

				if (val < 16) {
					hexValue.append("0");
				}

				hexValue.append(Integer.toHexString(val));
			}

			return hexValue.toString();
		} catch (NoSuchAlgorithmException e) {
			return null;
		}
	}

	/**
	 * 删除文件或目录 
	 * @param file
	 */
	public static boolean deleteFileOrDir(File file) {
		if (file.isDirectory())
		{
			// 目录
			File[] fileList = file.listFiles();
			for (int i = 0; i < fileList.length; i++)
			{
				if (fileList[i].isDirectory())
				{
					deleteFileOrDir(fileList[i]);
				}
				fileList[i].delete();
			}
			return file.delete();
		} else {
			// 文件
			return file.delete();
		}
	}

	/**
	 * 删除文件或目录 
	 * @param fileName
	 */
	public static boolean deleteFileOrDir(String fileName) {
		File file = new File(fileName);
		return deleteFileOrDir(file);
	}

	/**
	 * 取得系统换行符 
	 * @return
	 */
	public static String getSystemLineSep() {

		// 系统换行符 
		String strLineSep = System.getProperty("line.separator");
		return strLineSep;
	}

	/**
	 * 取得文件名分隔符 ("/" on UNIX "\" on WINDOWS) 
	 * @return
	 */
	public static String getSystemFileSep() {

		// 文件名分隔符 
		String strFileSep = System.getProperty("file.separator");
		return strFileSep;
	}

	/**
	 * 判断字符串是否是数字型
	 * @param str 字符串
	 * @param clazz 数值类型
	 * @return
	 */
	public static boolean isNumeric(String str, Class<? extends Number> clazz)
	{
		try
		{
			if (clazz.equals(Byte.class))
			{
				Byte.parseByte(str);
			}
			else if (clazz.equals(Double.class))
			{
				Double.parseDouble(str);
			}
			else if (clazz.equals(Float.class))
			{
				Float.parseFloat(str);
			}
			else if (clazz.equals(Integer.class))
			{
				Integer.parseInt(str);
			}
			else if (clazz.equals(Long.class))
			{
				Long.parseLong(str);
			}
			else if (clazz.equals(Short.class))
			{
				Short.parseShort(str);
			}
		}
		catch (NumberFormatException nfe)
		{
			return false;
		}

		return true;
	}

	/**
	 * 将原文件写到指定的目标文件 
	 * @param originalFile
	 * @param destFile
	 * @throws IOException
	 */
	public static void writeFile(String originalFile, String destFile) throws IOException {

		File fileOriginal = new File(originalFile);

		// 取得缓冲输入流 
		BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileOriginal));

		File fileDest = new File(destFile);

		// 定义缓冲输出流 
		BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fileDest));

		byte[] bufferData = new byte[8192];

		// 读取输入流中的数据，写入到输出流 
		while (bis.read(bufferData) != -1) {
			bos.write(bufferData);
		}

		// 关闭流 
		bos.close();
		bis.close();
	}

	/**
	 * 判断文件是否存在
	 * @param fileName
	 * @return
	 */
	public static boolean isFileExists(String fileName) {
		File f = new File(fileName);
		return f.exists();
	}

	/**
	 * 生成32位的UUID.
	 * @return
	 */
	public static String getUUID() {
		String strUUID = UUID.randomUUID().toString();
		return strUUID.replaceAll("-", "");
	}

	
	/**
	 * 格式化目录 -- 此方法的作用是增强目录的通用性
	 * @param dir
	 * @return
	 */
	public static String formatDir(String dir) {
		if(File.separatorChar == '/'){ // On Unix OS
			return dir.replace('\\', File.separatorChar);
		}
		return dir;
	}
	
	/**
	 * 将unicode解码成中文
	 * @param value
	 * @return
	 */
	public static String unicode2Chinese(String value) {
		Pattern pattern = Pattern.compile("(\\\\u(\\p{XDigit}{4}))");
		Matcher matcher = pattern.matcher(value);
		char ch;
		while (matcher.find()) {
			ch = (char) Integer.parseInt(matcher.group(2), 16);
			value = value.replace(matcher.group(1), ch + "");
		}
		return value;
	}
	
	/**
	 * 将中文编码成unicode
	 * @param value
	 * @return
	 */
	public static String chinese2Unicode(String value) {
		String strRet = "";
		for (int i = 0; i < value.length(); i++) {
			strRet += "\\u" + Integer.toHexString(value.charAt(i));
		}
		return strRet;
	}
	
	/**
	 * 将字节数换算成相应单位的数量
	 * @param bitNum
	 * @return
	 */
	public static String getNiceFileSize(long bitNum){
		int _K = 1024;
		int _M = _K*1024;
		
		if(bitNum < _M){
			if(bitNum < _K){
				return String.valueOf(bitNum) + 'B';
			}else{
				return String.valueOf(Math.ceil(bitNum/_K)) + 'K';
			}
			
		}else{
			return String.valueOf(Math.ceil(100*bitNum/_M)/100) +'M';
		}
	}
	
	/**
	 * 将汉字转换为全拼
	 * 
	 * @param src
	 * @return String
	 */
	public static String getPinYin(String src) {
		char[] t1 = src.toCharArray();
		String[] t2 = new String[t1.length];
		
		// 设置汉字拼音输出的格式
		HanyuPinyinOutputFormat t3 = new HanyuPinyinOutputFormat();
		t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
		t3.setVCharType(HanyuPinyinVCharType.WITH_V);
		
		String t4 = "";
		int t0 = t1.length;
		try {
			for (int i = 0; i < t0; i++) {
				// 判断能否为汉字字符
				// System.out.println(t1[i]);
				if (Character.toString(t1[i]).matches("[\u4E00-\u9FA5]+")) {
					t2 = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3);// 将汉字的几种全拼都存到t2数组中
					t4 += t2[0];// 取出该汉字全拼的第一种读音并连接到字符串t4后
				} else {
					// 如果不是汉字字符，间接取出字符并连接到字符串t4后
					t4 += Character.toString(t1[i]);
				}
			}
		} catch (BadHanyuPinyinOutputFormatCombination e) {
			e.printStackTrace();
		}
		return t4;
	}
	
	/**
	 * 提取每个汉字的首字母
	 * 
	 * @param str
	 * @return String
	 */
	public static String getPinYinHeadChar(String str) {
		String convert = "";
		for (int j = 0; j < str.length(); j++) {
			char word = str.charAt(j);
			// 提取汉字的首字母
			String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(word);
			if (pinyinArray != null) {
				convert += pinyinArray[0].charAt(0);
			} else {
				convert += word;
			}
		}
		return convert;
	}
}